{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "# Translating Plate at 20°"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "using PotentialFlow"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Set up"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "At the beginning of every time-step, we first determine the bound vortex sheet strength required to satisfy the no-flow-through condition, then velocity of all vortex elements:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "compute_ẋ! (generic function with 1 method)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function compute_ẋ!(ẋ, x, t)\n",
    "    plate, ambient_sys = x\n",
    "    motion, ambient_vel = ẋ\n",
    "    \n",
    "    Plates.enforce_no_flow_through!(plate, motion, ambient_sys, t)\n",
    "    \n",
    "    reset_velocity!(ẋ, x)\n",
    "    self_induce_velocity!(ẋ, x, t)\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Once we have advected all the vortex elements, we release new segments of the vortex sheet from the edges of the plate.\n",
    "Since we are dealing with a low angle of attack case, only the trailing edge will be forced to satisfy the Kutta condition.\n",
    "Vorticity released from the leading edge will instead follow the leading edge suction parameter (LESP) criteria described in [Ramesh et al. 2014](https://doi.org/10.1017/jfm.2014.297)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "shed_new_vorticity! (generic function with 3 methods)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function shed_new_vorticity!(sheet₊, sheet₋, plate, motion, t, lesp = 0.0, tesp = 0.0)\n",
    "    z₊ = (sheet₊.blobs[end].z + 2plate.zs[end])/3\n",
    "    z₋ = (sheet₋.blobs[end].z + 2plate.zs[1])/3\n",
    "    \n",
    "    segment₊ = Vortex.Blob.([sheet₊.blobs[end].z, z₊], [0.5, 0.5], δ)\n",
    "    segment₋ = Vortex.Blob.([sheet₋.blobs[end].z, z₋], [0.5, 0.5], δ)\n",
    "    Plates.enforce_no_flow_through!(plate, motion, (sheet₊, sheet₋), t)\n",
    "    \n",
    "    Γ₊, Γ₋, _, _ = Plates.vorticity_flux!(plate, segment₊, segment₋, t, lesp, tesp);\n",
    "    Vortex.Sheets.append_segment!(sheet₊, z₊, Γ₊)\n",
    "    Vortex.Sheets.append_segment!(sheet₋, z₋, Γ₋)\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "### Discretize the plate and sheets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "We are simulating a flat plate with zero thickness impulsively translating horizontally at a fixed velocity and angle of attack"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "L = 2.0   # chord length\n",
    "N = 128   # number of plate control points (distributed along a extrema Chebyshev grid)\n",
    "\n",
    "ċ = 0.5L  # translation velocity\n",
    "α = π/9   # angle of attack\n",
    "\n",
    "Δt = 1e-2; # time step\n",
    "\n",
    "plate = Plate(N, L, zero(Complex128), α)\n",
    "motion = Plates.RigidBodyMotion(ċ, 0.0);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "We place the initial segments of the vortex sheets perpendicularly off each edge of the plate.\n",
    "The sheets themselves are represented as discrete vortex blobs, all with the same blob radius `δ`.\n",
    "Both segments initially have unit circulation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Vortex Sheet: L ≈ 0.01, Γ = 1.0, δ = 0.01"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Δz₀ = im*Δt*exp(im*α)\n",
    "z₋, z₊ = plate.zs[[1,N]]\n",
    "\n",
    "δ = 0.01\n",
    "\n",
    "sheet₊ = Vortex.Sheet([0.5, 1.5] .* Δz₀ + z₊, [0.0, 1.0], δ)\n",
    "sheet₋ = Vortex.Sheet([0.5, 1.5] .* Δz₀ + z₋, [0.0, 1.0], δ)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We then adjust the circulation in the vortex sheet segments to satisfy the leading and trailing edge suction parameters.\n",
    "Since we want the Kutta condition to be satisfied at the trailing edge, we set the critical trailing edge suction parameter to zero."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Vortex Sheet: L ≈ 0.01, Γ = -0.193, δ = 0.01"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lesp = 0.1\n",
    "tesp = 0.0\n",
    "Plates.enforce_no_flow_through!(plate, motion, (), 0)\n",
    "\n",
    "Γ₊, Γ₋, _, _ = Plates.vorticity_flux(plate, sheet₊, sheet₋, 0, lesp, tesp);\n",
    "\n",
    "sheet₊ = Vortex.Sheet([0.5, 1.5] .* Δz₀ + z₊, [0.0, Γ₊], δ)\n",
    "sheet₋ = Vortex.Sheet([0.5, 1.5] .* Δz₀ + z₋, [0.0, Γ₋], δ)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "We organize the flow elements into the plate and ambient elements."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "ambient_sys = (sheet₊, sheet₋)\n",
    "sys = (plate, ambient_sys)\n",
    "ẋs = (motion, allocate_velocity(ambient_sys));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Time-Marching"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "We use forward Euler to evolve the system and apply filtering on both the leading and trailing edge vortex sheets to surpress small-scale instabilities."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "tf = 9\n",
    "T = 0:Δt:tf\n",
    "\n",
    "for t in T\n",
    "    TimeMarching.forward_euler!(sys, sys, t, Δt, compute_ẋ!, advect!, ẋs)\n",
    "\n",
    "    # Redistribute the points along the free vortex sheet to be at least 2UΔt\n",
    "    # apart from each other.  At the same time, we filter out any length scales\n",
    "    # along the sheet shorter than 6UΔt\n",
    "    for s in 1:2\n",
    "        Sheets.arclength(sys[2][s]) ≥ 3Δt && Sheets.filter!(sys[2][s], 2Δt, 6Δt)\n",
    "    end\n",
    "    \n",
    "    shed_new_vorticity!(sys[2][1], sys[2][2], sys[1], ẋs[1], t + Δt, lesp, tesp)\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Plotting"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Most flow elements in the library has [plot recipes](https://github.com/JuliaPlots/RecipesBase.jl) defined for them.\n",
    "So once [`Plots.jl`](https://github.com/JuliaPlots/Plots.jl) is installed along with the appropriate backend, we can directly call `plot` on the potential flow elements."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       ":colorbrewer"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "using Plots\n",
    "clibrary(:colorbrewer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<img src=\"\" />"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "plot(sys, ratio = 1, color = :RdBu_r, clims = (-0.5, 0.5), \n",
    "     legend = :none, colorbar = :right, colorbar_title = \"\\$\\\\gamma\\$\", \n",
    "     size = (600, 150), grid = false)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 0.6.1-pre",
   "language": "julia",
   "name": "julia-0.6"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "0.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
